#include "terminal.h"
#include "time.h"
#include "zigbee.h"
#include "DevLog.h"
#include "bsp_string.h"

/**
 * @brief 函数声明;
 */
void Terminal_Help_Ack(void);
void Terminal_Reboot_Ack(void);
void Terminal_Time_Set_Ack(void);
void Terminal_Time_Get_Ack(void);
void Terminal_Reset_Ack(void);
void Terminal_Mac_Get_Ack(void);
void Terminal_Net_Get_Ack(void);
void Terminal_Addr_Get_Ack(void);
void Terminal_Clear_Ack(void);
void Terminal_LogShake_Ack(void);
void Terminal_Open_Ack(void);
void Terminal_Ping_Ack(void);

/**
 * @brief 终端指令初始化;
 *   串口波特率: 115200
 *   串口通信参数: 8N1
 */
void Terminal_Init(void)
{
    T_USART_Init();
}

// 字符串判断;
char is_string(const char* Src, const char* Dst)
{
    if(strcmp(Src, Dst) == 0) { return 1; }
    return 0;
}
char is_nstring(const char* Src, const char* Dst, int Len)
{
    if(strncmp(Src, Dst, Len) == 0) { return 1; }
    return 0;
}

// 打印数据 HEX
//static void Print_Buf_Hex(const void * Buf, int Len)
//{
//	int i=0;
//	uint8_t* pData = (uint8_t*)Buf;
//	for(i=0; i<Len; i++)
//	{
//		printf("%02X ", pData[i]);
//	}
//	if(Len>0) { printf("\n"); }
//}

/**
 * @brief 获取当前指令
 * 
 * @param CmdStr 
 * @return Terminal_Cmd_t 
 */
Terminal_Cmd_t Terminal_Cmd_Get(char* CmdStr)
{
    if(is_string(CmdStr, "help")) { return TERMINAL_HELP; }
    else if(is_string(CmdStr, "reboot")) { return TERMINAL_REBOOT; }
    else if(is_string(CmdStr, "reset")) { return TERMINAL_RESET; }
#if ZIGBEE_SERVER_ENABLE
    else if(is_string(CmdStr, "log_clear")) { return TERMINAL_LOG_CLEAR; }
    else if(is_string(CmdStr, "log_shake")) { return TERMINAL_LOG_SHAKE; }
    else if(is_string(CmdStr, "log_open")) { return TERMINAL_LOG_OPEN; }
    else if(is_nstring(CmdStr, "time_set", strlen("time_set"))) { return TERMINAL_TIME_SET; }
    else if(is_string(CmdStr, "time_get")) { return TERMINAL_TIME_GET; }
#endif
    else if(is_string(CmdStr, "mac_get")) { return TERMINAL_MAC_GET; }
    else if(is_string(CmdStr, "net_get")) { return TERMINAL_NET_GET; }
    else if(is_string(CmdStr, "addr_get")) { return TERMINAL_ADDR_GET; }
#if ZIGBEE_CLIENT_ENABLE
	else if(is_string(CmdStr, "ping")) { return TERMINAL_PING; }
#endif
    return TERMINAL_NULL;
}

// 终端发送数据
void Terminal_Send(const char * StrAck)
{
    T_USART_Send(StrAck, strlen(StrAck));
}


/**
 * @brief 终端数据处理
 * 
 */
void Terminal_Data_Handle(void)
{
    if(T_Usart.Flag != 1) { return; }
    
    Terminal_Cmd_t Cmd = Terminal_Cmd_Get((char*)T_Usart.Buf);

    switch (Cmd)
    {
    /**
     * @brief 帮助
     */
    case TERMINAL_HELP:
    {
		Terminal_Help_Ack();
    } break;
    /**
     * @brief 重启
     */
    case TERMINAL_REBOOT:
    {
        Terminal_Reboot_Ack();
        delay_ms(3000);
        __set_FAULTMASK(1);//关闭总中断
        NVIC_SystemReset();//请求单片机重启
    } break;
    /**
     * @brief 重置网络;
     */
    case TERMINAL_RESET:
    {
        Terminal_Reset_Ack();
    } break;
    /**
     * @brief 查询震动记录
     */
    case TERMINAL_LOG_CLEAR:
    {
        Terminal_Clear_Ack();
    } break;
    /**
     * @brief 查询震动记录
     */
    case TERMINAL_LOG_SHAKE:
    {
        Terminal_LogShake_Ack();
    } break;
    /**
     * @brief 查询开窗记录
     */
    case TERMINAL_LOG_OPEN:
    {
        Terminal_Open_Ack();
    } break;
    /**
     * @brief 设置时间
     */
    case TERMINAL_TIME_SET:
    {
		Terminal_Time_Set_Ack();
    } break;
    /**
     * @brief 获取时间
     */
    case TERMINAL_TIME_GET:
    {
        Terminal_Time_Get_Ack();
    } break;
    /**
     * @brief 获取MAC
     */
    case TERMINAL_MAC_GET:
    {
        Terminal_Mac_Get_Ack();
    } break;
    /**
     * @brief 获取网络
     */
    case TERMINAL_NET_GET:
    {
        Terminal_Net_Get_Ack();
    } break;
    /**
     * @brief 获取Addr
     */
    case TERMINAL_ADDR_GET:
    {
        Terminal_Addr_Get_Ack();
    } break;
    /**
     * @brief Ping 服务端;
     */
    case TERMINAL_PING:
    {
        Terminal_Ping_Ack();
    } break;
    default:
    { } break;
    }

    T_USART_RevBuf_Clear();
}

/**
 * @brief Help 指令响应
*/
void Terminal_Help_Ack(void)
{
    printf("Commands:\n");
    printf("addr_get\t  Get device lora short addr.\n");
#if ZIGBEE_SERVER_ENABLE
    printf("log_clear\t Clear all device log.\n");
    printf("log_shake\t Show all window shake log.\n");
    printf("log_open \t Show all window open log.\n");
#endif
    printf("mac_get  \t Get device lora mac addr.\n");
    printf("net_get  \t Get device lora net state.\n");
#if ZIGBEE_CLIENT_ENABLE
    printf("ping     \t Zigbee client check net is connect?\n");
#endif
    printf("reboot   \t Root device.\n");
    printf("reset    \t Device lora net will reset and reconnect.\n");
#if ZIGBEE_SERVER_ENABLE
    printf("time_get \t Get device rtc time.\n");
    printf("time_set \t Set device rtc time.\n");
#endif
}

/**
 * @brief 重启响应
*/
void Terminal_Reboot_Ack(void)
{
    printf("System will reboot after 3 seconds\n");
}

/**
 * @brief 获取本地时间
*/
void Terminal_Time_Set_Ack(void)
{
    uint32_t i=0, idx=0;
    uint32_t Len = strlen("time_set");

    if(T_Usart.Len==Len) 
    {
        printf("time set no params, please send as time_set 1648045310\n");
        return ;
    }
    if(T_Usart.Buf[Len] != ' ')
    {
        printf("time set format is error, please send as time_set 1648045310\n");
        return ;
    }

    for(i=Len; i<T_Usart.Len; i++)          // 起始位置;
    {
        if(T_Usart.Buf[i] != ' ') { break; }
    }
    idx = i;

    uint32_t timeStamp = 0;
    int32_t ret = Bsp_Str2Uint((char *)&T_Usart.Buf[idx], T_Usart.Len-idx, &timeStamp);
    if(ret != 0)
    {
        printf("time set format is error, please send as time_set 1648045310\n");
        return ;
    }
    time_set(timeStamp);
    printf("time set %d [%s] is ok.\n", timeStamp, time_to_str(timeStamp));
}


/**
 * @brief 获取本地时间
*/
void Terminal_Time_Get_Ack(void)
{
    printf("\n%s\n", time_to_str(time_get()));
}

/**
 * @brief 重置响应;
 */
void Terminal_Reset_Ack(void)
{
#if ZIGBEE_CLIENT_ENABLE
    printf("reset zigbee net, zigbee net will reconnect.\n");
    ZigBee_Client_Reset();
#endif
#if ZIGBEE_SERVER_ENABLE
    printf("1. reset zigbee net, zigbee net will reconnect.\n");
    printf("2. reset log, all log will be clean.\n");
    ZigBee_Server_Reset();
    DevLog_Shake_Clear();
    DevLog_Open_Clear();
#endif
    // delay_ms(1000);
    // __set_FAULTMASK(1);//关闭总中断
    // NVIC_SystemReset();//请求单片机重启
}

/**
 * @brief 重置响应;
 */
void Terminal_Mac_Get_Ack(void)
{
    extern ZigBee_Property_t Zigbee_Property;
    printf("device mac addr is:\n");
    printf("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",\
        Zigbee_Property.Mac[0], Zigbee_Property.Mac[1], Zigbee_Property.Mac[2],\
        Zigbee_Property.Mac[3], Zigbee_Property.Mac[4], Zigbee_Property.Mac[5],\
        Zigbee_Property.Mac[6], Zigbee_Property.Mac[7]\
        );
}

/**
 * @brief 设备网络响应;
 */
void Terminal_Net_Get_Ack(void)
{
    bsp_err_t Err;
    uint16_t Pan_ID=0;
    Err = ZigBee_Get_PanID(&Pan_ID, 1000);
    if(Err != TRUE)
    {
        printf("zigbee net state get error, please check zigbee module.\n");
        return ;
    }
    
    if(Pan_ID == 0xffff)
    {
        printf("zigbee net is not connect, pan id is %04X.\n", Pan_ID);
    }
    else if(Pan_ID != 0xffff)
    {
        printf("zigbee net is connect, pan id is %04X.\n", Pan_ID);
    }
}

/**
 * @brief 设备网络响应;
 */
void Terminal_Addr_Get_Ack(void)
{
    bsp_err_t Err;
    uint16_t ShortAddr=0;
    Err = ZigBee_Get_ShortAddr(&ShortAddr, 1000);
    if(Err != TRUE)
    {
        printf("zigbee short addr get error, please check zigbee module.\n");
        return ;
    }
    
    if(ShortAddr == 0xffff)
    {
        printf("zigbee net is not connect, short addr is %04X.\n", ShortAddr);
        return ;
    }
    else if(ShortAddr != 0xffff)
    {
        printf("zigbee short addr is %04X.\n", ShortAddr);
        return ;
    }
}

/**
 * @brief 清除日志
 * 
 */
void Terminal_Clear_Ack(void)
{
    printf("Shake and open log will be clear.\n");
    DevLog_Shake_Clear();
    DevLog_Open_Clear();
}

/**
 * @brief 打印日志
 * 
 */
void Terminal_LogShake_Ack(void)
{
    printf("/********************* Shake Log *************************/\n");
    DevLog_Shake_All_Print();
    printf("/*********************************************************/\n");
}

/**
 * @brief 打印日志
 * 
 */
void Terminal_Open_Ack(void)
{
    printf("/********************* Open Log *************************/\n");
    DevLog_Open_All_Print();
    printf("/*********************************************************/\n");
}

/**
 * @brief 心跳
 * 
 */
void Terminal_Ping_Ack(void)
{
    bsp_err_t Err;
    Err = Client_Ping(2000);
    if(Err == ERR_NO_ACK)
    {
        printf("zigbee server not ack, please check zigbee sever.\n");
        return ;
    }
    else if(Err == FALSE)
    {
        printf("zigbee server ack data is err, please check zigbee sever.\n");
        return ;
    }
    else {
        printf("zigbee client and server are ok.\n");
        return ;
    }
}
